﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Configuration;
using System.Web;
using System.Data;
using System.Xml;
using DAL = KC.DataAccess.MV;

namespace KC.Business.Web
{
	public class MV8
	{
		public static IQueryable<DAL.Post> GetTopPosts(int PostQty)
		{
			DAL.MV8DataContext dc = new DAL.MV8DataContext(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString);
			var result = (from p in dc.Posts where p.isEnabled orderby p.ID descending select p).Take(PostQty).AsQueryable<DAL.Post>();
			foreach (DAL.Post p in result)
				p.Body = KC.Business.Text.Encoding.BlogDecodeForRendering(p.Body);
			return result;
		}
		public static IQueryable<DAL.Post> GetTopPosts(int PostQty, int skip)
		{
			DAL.MV8DataContext dc = new DAL.MV8DataContext(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString);
			return (from p in dc.Posts where p.isEnabled orderby p.ID descending select p).Skip(skip).Take(PostQty).AsQueryable<DAL.Post>();
		}
		public static IQueryable<DAL.Gallery> GetTopPics(int PicQty)
		{
			DAL.MV8DataContext dc = new DAL.MV8DataContext(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString);
			return (from g in dc.Galleries 
					where g.Filename.Length > 0 && g.ThumbnailFilename.Length > 0 && !g.isDeepZoom
					orderby g.id descending 
					select g).Take(PicQty).AsQueryable<DAL.Gallery>();
		}
		public static int GetPostCount()
		{
			return new DAL.MV8DataContext(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString).Posts.Count();
		}

		public static DataTable GetMonthlyHits()
		{
			return KC.DataAccess.Global.Global.CallSql_Sproc(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString, @"GetMonthlyHits");
		}
		public static DataTable GetRecentReferrers(int qty)
		{
			string query =
				"select top " + qty.ToString() + " Referrer from Activities where \r\n" +
				" referrer is not null and \r\n" +
				" referrer <> \'\' and \r\n" +
				" referrer not like '%.google%' and \r\n" +
				" referrer not like '%.google%' and \r\n" +
				" referrer not like '%search%' and \r\n" +
				" referrer not like '%ask.com%' and \r\n" +
				" referrer not like '%flickr.%' and \r\n" +
				" referrer not like '%.bing.%' and \r\n" +
				" referrer not like '%sitemap.html' and \r\n" + 
				" referrer not like '%localhost%' and " +
				" referrer not like '%kevinconnolly2016.com%' and ";
			foreach (string domain in KC.Constants.Domains.MyDomains)
				query += " referrer not like \'%" + domain + "%\' and \r\n";
			query +=
				" (select COUNT(id) from Blacklist where domain<>'' and Referrer like '%' + domain + '%') = 0 and \r\n" +
				" (select COUNT(id) from BannedWords where Referrer like '%' + word + '%') = 0 \r\n" +
				"order by ID desc";

			DataTable dt = KC.DataAccess.Global.Global.CallSql_Query(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString, query);
			foreach (DataRow dr in dt.Rows) {
				string url = HttpUtility.HtmlEncode(HttpUtility.UrlDecode(dr[0].ToString()));
				if (url.Contains("://"))
					url = url.Substring(url.IndexOf("://") + 3);
				if (url.Length > 60)
					url = url.Substring(0, 55) + "[...]";
				dr[0] = url; }

			//for (int i = dt.Rows.Count - 1; i >= 0; i--)
			//    for (int j = 0; j < dt.Rows.Count; j++)
			//        if (i != j && dt.Rows[i][0].ToString().ToLower() == dt.Rows[j][0].ToString().ToLower()) {
			//            dt.Rows.RemoveAt(i);
			//            break; }

			while (dt.Rows.Count > qty)
				dt.Rows.RemoveAt(qty-1);

			return dt;
		}
		public static dynamic GetRecentSearches(int qty)
		{
			return (from s2 in
						(from s in (new DAL.MV8DataContext(ConfigurationManager.ConnectionStrings["MV8"].ConnectionString).SearchResults)
						 orderby s.ID descending
						 select new { s.ID, s.Engine, s.Query })
					select new { s2.Engine, s2.Query }).Take(qty);
		}

		public enum RequestType { Invalid, None, Post, Archives, Categories, Tags, AffiliatePage }

		/// <summary>Given a request, detects the request type</summary>
		/// <param name="Request">Request to validate</param>
		/// <returns>RequestType enum representing the type of request</returns>
		public static RequestType DetectRequestType(string Request, out Dictionary<string,string> values)
		{
			values = new Dictionary<string,string>();
			if (string.IsNullOrEmpty(Request)) return RequestType.Invalid;
			Request = Request.ToLower();
			if (string.IsNullOrEmpty(Request)) throw new ArgumentNullException("Request");
			System.Collections.Specialized.NameValueCollection QueryString = HttpUtility.ParseQueryString(Request.Replace("?", "?randomxx-8f8d989af&"));
			if (QueryString == null) return RequestType.None;

			// Detect Archives
			if (Request.ToLower().Contains("archives.aspx") || Request.Contains("maxarch") || Request.Contains("minarch"))
			{
				DateTime min=DateTime.MinValue, max = DateTime.MaxValue;
				if (QueryString["minarch"] != null && DateTime.TryParse(QueryString["minarch"], out min)) values.Add("minarch",min.ToString("MM/dd/yyyy"));
				if (QueryString["maxarch"] != null && DateTime.TryParse(QueryString["maxarch"], out max)) values.Add("maxarch",min.ToString("MM/dd/yyyy"));
				if (min > DateTime.MinValue || max < DateTime.MaxValue) return RequestType.Archives;
				else return RequestType.Invalid;
			}

			// Detect Categories
			if (Request.ToLower().Contains("categories.aspx"))
			{
				int id;
				if (QueryString["id"] != null && int.TryParse(QueryString["id"], out id)) values.Add("id", id.ToString());
				if (QueryString["cid"] != null && int.TryParse(QueryString["cid"], out id)) values.Add("cid", id.ToString());
				if (QueryString["catid"] != null && int.TryParse(QueryString["catid"], out id)) values.Add("catid", id.ToString());
				return RequestType.Categories;
			}

			// Detect Tags
			if (Request.ToLower().Contains("tags.aspx"))
			{
				int id;
				if (QueryString["id"] != null && int.TryParse(QueryString["id"], out id)) values.Add("id", id.ToString());
				if (QueryString["tid"] != null && int.TryParse(QueryString["tid"], out id)) values.Add("tid", id.ToString());
				if (QueryString["tagid"] != null && int.TryParse(QueryString["tagid"], out id)) values.Add("tagid", id.ToString());
				return RequestType.Tags;
			}

			// Detect Post
			if (Request.ToLower().Contains("post.aspx") || QueryString["id"] != null || QueryString["title"] != null)
			{
				// Unfortunately, I've used a bunch of different formats over the years... Therefore...
				if (QueryString["id"] != null && !string.IsNullOrEmpty(QueryString["id"])) values.Add("id", QueryString["id"]);
				else if (QueryString["pid"] != null && !string.IsNullOrEmpty(QueryString["pid"])) values.Add("id", QueryString["pid"]);
				else if (QueryString["postid"] != null && !string.IsNullOrEmpty(QueryString["postid"])) values.Add("id", QueryString["postid"]);
				else if (QueryString["post"] != null && !string.IsNullOrEmpty(QueryString["post"])) values.Add("id", QueryString["post"]);
				else if (QueryString["title"] != null && !string.IsNullOrEmpty(QueryString["title"])) values.Add("title", QueryString["title"]);

				int PostID;
				if (values.ContainsKey("id") && int.TryParse(values["id"], out PostID)) return RequestType.Post;
				else if (values.ContainsKey("title")) return RequestType.Post;
				else return RequestType.Invalid;
			}

			// Detect Affiliate Page
			if (Request.ToLower().Contains("page.aspx") && QueryString["title"] != null)
			{
				if (QueryString["title"] != null && !string.IsNullOrEmpty(QueryString["title"])) values.Add("title", QueryString["title"]);
				if (values.ContainsKey("title")) return RequestType.Post;
				else return RequestType.Invalid;
			}


			// Default: None
			return RequestType.None;
		}

		/// <summary>Updates tags on all Posts.</summary>
		public static int UpdateAllTags()
		{
			DAL.MV8DataContext dc = new DAL.MV8DataContext();
			int numSucceeded = 0;
			
			foreach (DAL.Post p in dc.Posts)
				try
				{
					UpdateTags(p, ref dc);
					numSucceeded++;
				}
				catch (Exception ex)
				{
					KC.Logging.Logger.LogError(KC.Logging.Logger.Project.KcArchitecture, Logging.Logger.ErrorLevel.Error, ex.ToString());
				}
			dc.Dispose();
			return numSucceeded;
		}
		/// <summary>Updates tags on a Post.</summary>
		/// <param name="p">Post to update tags on</param>
		/// <param name="dc">DataContext</param>
		public static void UpdateTags(DAL.Post p, ref DAL.MV8DataContext dc)
		{
			if (dc == null)
				throw new ArgumentNullException("dc", "cannot connect to a null data context");
			if (p == null)
				throw new ArgumentNullException("p", "Cannot update tags on a null Post");

			dc.TagToPosts.DeleteAllOnSubmit(p.TagToPosts);
			dc.SubmitChanges();
			string lowerbody = p.Body.ToLower(), lowertitle = p.Title.ToLower();
			foreach (DAL.Tag t in dc.Tags)
				if (lowerbody.Contains(t.Title.ToLower()) || lowertitle.Contains(t.Title.ToLower()))
				{
					DAL.TagToPost ttp = new DAL.TagToPost();
					ttp.PID = p.ID;
					ttp.TID = t.ID;
					dc.TagToPosts.InsertOnSubmit(ttp);
				}
			dc.SubmitChanges();
		}

		public static string MapGallery(string path)
		{
			if (string.IsNullOrEmpty(path)) return null;
			string GalleryPath = System.Configuration.ConfigurationManager.AppSettings["Gallery"];
			string Logicalpath = path.Replace(GalleryPath, ""); 
			string result = "http://www.kconnolly.net/Gallery/" + Logicalpath
				.Replace("\\", "/")
				.Replace("//kcws/c$/Websites/Gallery/", "");
			return result;
		}

		public static string FormatForXML(string data)
		{
			return data
				.Replace("&", "&amp;")
				.Replace("\"", "&quot;")
				.Replace("\'", "&apos;")
				.Replace("<", "&lt;")
				.Replace(">", "&gt;");
		}
	}
}
